package com.imooc.service.impl;

import com.imooc.enums.MsgActionEnum;
import com.imooc.enums.MsgSignFlagEnum;
import com.imooc.enums.SearchFriendsStatusEnum;
import com.imooc.mapper.*;
import com.imooc.utils.JsonUtils;
import io.netty.channel.Channel;
import com.imooc.netty.websocket.DataContent;
import com.imooc.netty.websocket.UserChannelRel;
import com.imooc.pojo.ChatMsg;
import com.imooc.pojo.FriendsRequest;
import com.imooc.pojo.MyFriends;
import com.imooc.pojo.Users;
import com.imooc.pojo.vo.FriendRequestVo;
import com.imooc.pojo.vo.MyFriendsVO;
import com.imooc.service.UserService;
import com.imooc.utils.QRCodeUtils;
import com.qiniu.common.QiniuException;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.apache.tomcat.jni.User;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapProperties;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.io.File;
import java.util.Date;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private QRCodeUtils qrCodeUtils;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private MyFriendsMapper myFriendsMapper;

    @Autowired
    private FriendsRequestMapper friendsRequestMapper;

    @Autowired
    private UsersMapperCustom usersMapperCustom;

    @Autowired
    private ChatMsgMapper chatMsgMapper;


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public boolean queryUsernameIsExist(String username) {

        Users users = new Users();

        users.setUsername(username);

     Users result = usersMapper.selectOne(users);

        return result != null ? true : false ;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Users queryUserForLogin(String username, String pwd) {

        Example userExample = new Example(Users.class);

       Example.Criteria criteria = userExample.createCriteria();

       criteria.andEqualTo("username",username);

       criteria.andEqualTo("password",pwd);

        Users result =  usersMapper.selectOneByExample(userExample);

        return result ;
    }

    @Autowired
    private Sid sid ;

    @Autowired
    private QiNiuServiceImpl qiNiuService;




    @Override
    public Users saveUser(Users users) throws QiniuException {

        String id = sid.nextShort();


        // 为每个用户生成一个唯一的二维码

        // 设置二维码的图片路径
        String qrCodePath = "./png/" + id + "qrcode.png";

        //生成二维码的图片
        qrCodeUtils.createQRCode(qrCodePath,"meixin_qrcode:"+users.getUsername());

        // 使用七牛云上传二维码图片
        String Url = qiNiuService.uploadFile(new File(qrCodePath));

        users.setQrcode(Url);

        users.setId(id);

        usersMapper.insert(users);

        return users;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Users updateUserInfo(Users users) {
        usersMapper.updateByPrimaryKeySelective(users);
        return queryUserById(users.getId());

    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public Users queryUserById(String id) {
        return usersMapper.selectByPrimaryKey(id);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Integer preconditionSearchFriends(String myUserId, String friendUsername) {

        Users user = queryUserInfoByUsrname(friendUsername);

        if(user == null){
                return SearchFriendsStatusEnum.USER_NOT_EXIST.status;
        }

        if(user.getId().equals(myUserId)){
            return SearchFriendsStatusEnum.NOT_YOURSELF.status;
        }

        Example mfe = new Example(MyFriends.class);
        Example.Criteria mfc = mfe.createCriteria();
        mfc.andEqualTo("myUserId",myUserId);
        mfc.andEqualTo("myFriendUserId",user.getId());
        MyFriends myFriendsRel =   myFriendsMapper.selectOneByExample(mfe);

        if(myFriendsRel != null){
            return SearchFriendsStatusEnum.ALREADY_FRIENDS.status;
        }

        return SearchFriendsStatusEnum.SUCCESS.status ;

    }

    public Users queryUserInfoByUsrname(String username){
        Example ue = new Example(Users.class);
        Example.Criteria uc = ue.createCriteria();
        uc.andEqualTo("username",username);
        return usersMapper.selectOneByExample(ue);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void sendFriendRequest(String myUserId, String friendUsername) {

          // 根据用户名把朋友的信息查询出来
          Users users = queryUserInfoByUsrname(friendUsername);

         // 查询发送好友请求的记录表
        Example fre = new Example(FriendsRequest.class);
        Example.Criteria frc = fre.createCriteria();
        frc.andEqualTo("sendUserId",myUserId);
        frc.andEqualTo("acceptUserId",users.getId());
        FriendsRequest friendsRequest = friendsRequestMapper.selectOneByExample(fre);

        if(friendsRequest == null){
            // 不是好友，也没发过添加好友的请求，则新增好友请求记录
            String requestId = sid.nextShort();

            FriendsRequest request = new FriendsRequest();

            request.setId(requestId);

            request.setSendUserId(myUserId);

            request.setAcceptUserId(users.getId());

            request.setRequestDataTime(new Date());

            friendsRequestMapper.insert(request);
        }

    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<FriendRequestVo> queryFriendRequestList(String acceptUserId) {
        return usersMapperCustom.queryFriendRequestList(acceptUserId);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void deleteFriendRequest(String sendUserId, String acceptUserId) {
        Example ue = new Example(FriendsRequest.class);
        Example.Criteria uc = ue.createCriteria();
        uc.andEqualTo("sendUserId",sendUserId);
        uc.andEqualTo("acceptUserId",acceptUserId);
         friendsRequestMapper.deleteByExample(ue);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void addFriendRequest(String sendUserId, String acceptUserId) {
                // 把请求从好友请求表中删除
                deleteFriendRequest(sendUserId,acceptUserId);
                 // 相互保存好友信息
                saveFriend(sendUserId, acceptUserId);
                saveFriend(acceptUserId,sendUserId);

        // 使用websocket 主动推送消息到请求发起者，更新他的通讯录为最新
        // 添加好友成功之后，并没有消息的列表，只有其中的一方发送消息，消息才会显示到主页中
        // 所以需要把用户添加本地的存储列表中先
        // 本地的通讯录列表当页面第一次打开的时候是从后端获取数据的，并同步到本地的存储，其它的时候是从本地的存储中获取数据的

      Channel  sendChannel =  UserChannelRel.get(sendUserId);

        if(sendChannel != null){
            DataContent dataContent = new DataContent();
            dataContent.setAction(MsgActionEnum.PULL_FRIEND.type);
            sendChannel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(dataContent)));
        }
    }


    @Transactional(propagation = Propagation.REQUIRED)
    void saveFriend(String sendUserId, String acceptUserId){
        MyFriends myFriends = new MyFriends();

        myFriends.setId(sid.nextShort());

        myFriends.setMyUserId(acceptUserId);

        myFriends.setMyFriendUserId(sendUserId);

        myFriendsMapper.insert(myFriends);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<MyFriendsVO> queryMyFriend(String userId) {
            List<MyFriendsVO> myFriendsVOS = usersMapperCustom.queryMyFriend(userId);
            return  myFriendsVOS;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public String saveMsg(ChatMsg chatMsg) {

        chatMsg.setId(sid.nextShort());

        chatMsg.setMsgId("");

        chatMsg.setCreateTime(new Date());

        chatMsg.setSignFlag(MsgSignFlagEnum.unsign.type);

        chatMsgMapper.insert(chatMsg);

        return chatMsg.getId();
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateMsgSigned(List<String> msgIdList) {

        usersMapperCustom.batchUpdateMsgSigned(msgIdList);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ChatMsg> getUnReadMsgList(String acceptUserId) {

         Example fre = new Example(ChatMsg.class);

          Example.Criteria frc = fre.createCriteria();

          frc.andEqualTo("acceptUserId",acceptUserId);

          frc.andEqualTo("signFlag",0);

          return  chatMsgMapper.selectByExample(fre);

    }
}
